package com.xiyu.service.repository.mailbox.folder;

import com.xiyu.service.enums.mailbox.folder.MailboxFolderTypeEnum;
import com.xiyu.service.model.mailbox.folder.MailboxFolder;
import com.xiyu.service.model.mailbox.folder.MailboxFolderTable;
import org.babyfish.jimmer.spring.repository.JRepository;

import java.util.Optional;
import java.util.List;

public interface MailboxFolderRepository extends JRepository<MailboxFolder, Long> {
    MailboxFolderTable mailboxFolderTable = MailboxFolderTable.$;

    default List<MailboxFolder> getMailboxFolderByAccountIds(List<Long> accountIds){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().in(accountIds))
                .orderBy(mailboxFolderTable.sort())
                .orderBy(mailboxFolderTable.id())
                .select(mailboxFolderTable)
                .execute();
    }

    default List<MailboxFolder> getMailboxFolderByAccountIdsAndFolderType(List<Long> accountIds, Integer folderType){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().in(accountIds))
                .where(mailboxFolderTable.folderType().eq(folderType))
                .orderBy(mailboxFolderTable.sort())
                .orderBy(mailboxFolderTable.id())
                .select(mailboxFolderTable)
                .execute();
    }

    default List<MailboxFolder> getMailboxFolderByAccountIdsAndFolderClass(List<Long> accountIds, Integer folderClass){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().in(accountIds))
                .where(mailboxFolderTable.folderClass().eq(folderClass))
                .orderBy(mailboxFolderTable.sort())
                .orderBy(mailboxFolderTable.id())
                .select(mailboxFolderTable)
                .execute();
    }

    default List<MailboxFolder> findByParentId(Long parentId){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.parentId().eq(parentId))
                .orderBy(mailboxFolderTable.sort())
                .orderBy(mailboxFolderTable.id())
                .select(mailboxFolderTable)
                .execute();

    };

    default Optional<MailboxFolder> findRootFolder(Long accountId){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.parentId().eq(0L))
                .select(mailboxFolderTable)
                .fetchOptional();
    }

    default Optional<MailboxFolder> findRootLabel(Long rootFolderId){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.folderType().eq(MailboxFolderTypeEnum.LABEL.getValue()))
                .where(mailboxFolderTable.parentId().eq(rootFolderId))
                .select(mailboxFolderTable)
                .fetchOptional();
    }

    default List<MailboxFolder> findLabelFolder(Long accountId, Long parentLabelId){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.folderType().eq(MailboxFolderTypeEnum.LABEL.getValue()))
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.id().ne(parentLabelId))
                .orderBy(mailboxFolderTable.sort())
                .orderBy(mailboxFolderTable.id())
                .select(mailboxFolderTable)
                .execute();
    }

    default Optional<MailboxFolder> findLabelByName(Long accountId, String labelName){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.folderType().eq(MailboxFolderTypeEnum.LABEL.getValue()))
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.name().eq(labelName))
                .select(mailboxFolderTable)
                .fetchOptional();
    }

    default void updateSort(Long folderId, Long sort){
        sql().createUpdate(mailboxFolderTable)
                .set(mailboxFolderTable.sort(), sort)
                .where(mailboxFolderTable.id().eq(folderId))
                .execute();
    }

    default void updateReadMailCount(Long folderId, Boolean isRead){
        sql().createUpdate(mailboxFolderTable)
                .set(mailboxFolderTable.readMailCount(), mailboxFolderTable.readMailCount().plus(isRead ? 1 : -1))
                .where(mailboxFolderTable.id().eq(folderId))
                .execute();
    }

    default void updateTopMailCount(Long folderId, Boolean isTop){
        sql().createUpdate(mailboxFolderTable)
                .set(mailboxFolderTable.topMailCount(), mailboxFolderTable.topMailCount().plus(isTop ? 1 : -1))
                .where(mailboxFolderTable.id().eq(folderId))
                .execute();
    }

    default void updateCount(Long folderId, Integer mailCount, Integer readMailCount, Integer topMailCount){
         sql().createUpdate(mailboxFolderTable)
                .set(mailboxFolderTable.mailCount(), mailCount)
                .set(mailboxFolderTable.readMailCount(), readMailCount)
                .set(mailboxFolderTable.topMailCount(), topMailCount)
                .where(mailboxFolderTable.id().eq(folderId))
                .execute();
    }

    default void updatePostOfficeNameEmpty(Long accountId, Integer folderType){
        sql().createUpdate(mailboxFolderTable)
                .set(mailboxFolderTable.postOfficeName(), "")
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.folderType().eq(folderType))
                .execute();
    }

    default void deletePostOfficeNameEmpty(Long accountId, Integer folderType){
        sql().createDelete(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.folderType().eq(folderType))
                .where(mailboxFolderTable.postOfficeName().eq(""))
                .execute();
    }

    default List<MailboxFolder> findSyncFolder(Long accountId){
        return sql().createQuery(mailboxFolderTable)
                .where(mailboxFolderTable.accountId().eq(accountId))
                .where(mailboxFolderTable.postOfficeName().ne(""))
                .select(mailboxFolderTable)
                .execute();
    }

    List<MailboxFolder> findByAccountIdAndFolderTypeAndFolderClass(Long accountId, Integer folderType, Integer folderClass);

    List<MailboxFolder> findByAccountIdAndFolderTypeAndName(Long accountId, Integer folderType, String name);

    List<MailboxFolder> findByFolderTypeAndName(Integer folderType, String name);

    Optional<MailboxFolder> findByAccountIdAndPostOfficeName(Long accountId, String postOfficeName);

    Optional<MailboxFolder> findFirstByParentIdAndName(Long parentId, String name);

}